package cn.wubo.sqlparser;

import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
import lombok.extern.slf4j.Slf4j;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
public class DruidSQLParser {

    public static void parser(String sql, String dbType) {
        DbType dt = DbType.valueOf(dbType);
        List<SQLStatement> sqlStatements = SQLUtils.parseStatements(sql, dt);

        sqlStatements.forEach(e -> {
            String newSQL = SQLUtils.toSQLString(e,dbType);
            log.debug("to: newSQL[{}]", newSQL);

            SchemaStatVisitor visitor = new SchemaStatVisitor(dt);
            e.accept(visitor);

            Map<TableStat.Name, TableStat> tables = visitor.getTables();
            Collection<TableStat.Column> columns = visitor.getColumns();
            List<TableStat.Condition> conditions = visitor.getConditions();

            if (Objects.nonNull(tables)) {
                tables.forEach((name, tableStat) -> {
                    if (tableStat.getCreateCount() > 0 || tableStat.getInsertCount() > 0) {
                        log.debug("to: table[{}]", name.getName().toLowerCase());
                        List<TableStat.Column> temps = columns.stream().filter(column -> Objects.equals(column.getTable().toLowerCase(), name.getName().toLowerCase())).collect(Collectors.toList());
                        temps.forEach(column -> {
                            log.debug("to: table[{}] column[{}]", column.getTable().toLowerCase(), column.getName().toLowerCase());
                            conditions.stream().filter(condition -> Objects.equals(condition.getColumn().getName().toLowerCase(), column.getName().toLowerCase()))
                                    .forEach(condition -> log.debug("to: table[{}] column[{}] condition[{}]", column.getTable().toLowerCase(), column.getName().toLowerCase(), condition));
                        });
                    } else if (tableStat.getSelectCount() > 0) {
                        log.debug("from: table[{}]", name.getName().toLowerCase());
                        List<TableStat.Column> temps = columns.stream().filter(column -> Objects.equals(column.getTable().toLowerCase(), name.getName().toLowerCase())).collect(Collectors.toList());
                        temps.forEach(column -> {
                            log.debug("from: table[{}] column[{}]", column.getTable().toLowerCase(), column.getName().toLowerCase());
                            conditions.stream().filter(condition -> Objects.equals(condition.getColumn().getName().toLowerCase(), column.getName().toLowerCase()))
                                    .forEach(condition -> log.debug("to: table[{}] column[{}] condition[{}]", column.getTable().toLowerCase(), column.getName().toLowerCase(), condition));
                        });
                    }
                });
            }
        });
    }
}
